home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
v8n06.arc
/
BSEARCH.ASM
next >
Wrap
Assembly Source File
|
1989-02-28
|
4KB
|
119 lines
; BSEARCH.ASM --- General purpose binary search routine (MS-DOS version)
; Copyright (c) 1989 Ziff Communications Co.
; PC Magazine * Ray Duncan
;
; Call with: BX = file handle
; CX = record length
; DS:DX = record buffer address
; SI = first (left) record number
; DI = last (right) record number
; ES:BP = key structure address
;
; where the key structure is:
; dw n length of key
; dw m offset of key in record
; db n dup (?) key value
;
; Returns: if record found
; Zero flag = set
; AX = record number
;
; if record not found
; Zero flag = clear
; AX = undefined
;
; All other registers preserved
_TEXT segment word public 'CODE'
extrn strcmp:near
assume cs:_TEXT
kbuff equ dword ptr [bp] ; key address
right equ word ptr [bp+4] ; last record number
left equ word ptr [bp+6] ; first record number
fbuff equ dword ptr [bp+8] ; file buffer address
flen equ word ptr [bp+12] ; file record size
fhandle equ word ptr [bp+14] ; file handle
public bsearch
bsearch proc near
cmp si,di ; first > last record?
jng bsch1 ; no, jump
ret ; record absent, end search
bsch1: push bx ; save registers
push cx
push ds
push dx
push si
push di
push es
push bp
mov bp,sp ; point to stack frame
mov ax,si ; calculate record number
add ax,di ; at middle of file segment
shr ax,1 ; (left + right) / 2
push ax ; save record number
; set file pointer...
mul cx ; set CX:DX = file offset
mov cx,ax ; (BX already = handle)
xchg dx,cx
mov ax,4200h ; fxn. 42 subf. 00H = seek
int 21h ; transfer to MS-DOS
; now read record....
mov cx,flen ; CX = record length
lds dx,fbuff ; DS:DX = record buffer
mov ah,3fh ; fxn 3fh = read
int 21h ; transfer to MS-DOS
les di,kbuff ; ES:DI = key structure
mov si,dx ; DS:SI = record buffer
add si,es:[di+2] ; DS:SI = key within record
mov bx,es:[di] ; BX = length of key
mov dx,bx ; DX = length of key
add di,4 ; ES:DI = address of key
call strcmp ; now compare keys
pop ax ; recover record number
jz bsch4 ; match found, exit
mov bx,fhandle ; set up to bisect file and
mov cx,flen ; perform recursive search
mov si,left
mov di,right
lds dx,fbuff
les bp,kbuff
jl bsch2 ; branch on key comparison
mov di,ax ; record < search key
dec di ; set right = current - 1
jmp bsch3
bsch2: mov si,ax ; record > search key
inc si ; set left = current + 1
bsch3: call bsearch ; inspect next middle record
bsch4: pop bp ; restore registers
pop es ; leaving Z flag undisturbed
pop di
pop si
pop dx
pop ds
pop cx
pop bx
ret ; and return to caller
bsearch endp
_TEXT ends
end